/* 5. 枚举( Enum )
  + 是一个常量的集合
  + 分类
    => 数字枚举
    => 字符串枚举
    => 混合枚举
  + 之前学习 js 的时候
    => 元素.addEventListener('click', () => {})
    => 元素.addEventListener('mouseenter', () => {})
    => 元素.addEventListener('mouseleave', () => {})
    => 元素.addEventListener('mouseover', () => {})
    => 元素.addEventListener('mouseout', () => {})
    => 元素.addEventListener('mousemove', () => {})
    => 元素.addEventListener('visibilitychange', () => {})
  + 在 http 传输协议内( content-type )
    => application/x-www-form-urlencoded
    => application/json
    => multipart/form-data
  + 为了避免出现问题
    => const query = 'application/x-www-form-urlencoded'
    => const json = 'application/json'
  + 枚举就是把一系列常量组合在一起, 让他们看起来就有关系
    => 你定义的枚举可以用来限制数据
*/
/* 5-1. 字符串枚举
  + 语法:
    enum 枚举名称 {
      key = value
    }
  + 当你使用字符串枚举去限制一个数据的时候
    => 那么这个数据可选地值, 只能是该枚举内的值
    => 枚举的值和字符串不相等
*/
// 定义一个枚举
// enum paramsType {
//   Query = 'application/x-www-form-urlencoded',
//   Json = 'application/json'
// }
// enum colorType {
//   Green = 'green',
//   Red = 'red',
//   Yellow = 'yellow'
// }
// // 使用枚举
// // 因为你的 color 被 colorType 这个枚举限制了, 他就要求你必须要用枚举内的值
// // 又认为, 你写的 'green' 不是枚举内的值
// // const color: colorType = 'green'
// const color: colorType = colorType.Green
/* 5-2. 数字枚举
  + 其实就是枚举的值是一个 数值类型
  + 注意:
    => 在写的时候, 可以不写值
    => 如果你不写值, 默认第一个值是 0, 后面的依次 +1
    => 如果你从中间某一个开始不写, 那么默认是上一个值 +1
  + 数字枚举支持反向映射
    => 例子
      enum NumberType {
        AA, // => 0
        BB  // => 1
      }
    => 被 JS 正常编译为一个对象
      const NumberType = {
        AA: 0,
        BB: 1,
        0: 'AA',
        1: 'BB'
      }
*/
// enum NumberType {
//   AA, // => 0
//   BB  // => 1
// }
//
// enum NumberType2 {
//   AA = 10,
//   BB,       // => 11
//   CC = 30.2,
//   DD        // => 31.2
// }
/* 5-3. 混合枚举
  + 值有字符串也有数值( 不推荐 )
  + 注意: 如果你写在某一个字符串值后面的数字枚举, 必须要赋值
*/
// enum AbcType {
//   AA,
//   BB = 'hello world',
//   CC = 10,
//   DD
// }
/* 5-4. 常量枚举
  + 是值在定义枚举的前面加一个 const 关键字
  + 此时在编译结构的时候, 不会编译枚举对象
  + 而是直接编译枚举值
*/
// const enum ColorType {
//   Green = 'green',
//   Red = 'red'
// }
// console.log(ColorType.Red)

/* 6. 泛型
  + 泛型: 预设( 挖坑 )
    => 在你定义接口的时候, 预设一个类型槽位
    => 当你使用接口的时候, 填充槽位
*/
// interface UserType1 {
//   name: string
//   age: number
//   gender: string
// }
// interface UserType2 {
//   name: string
//   age: number
//   gender: number
// }
// // 在定义接口的时候, 留一个槽位
// interface UserType<GX> {
//   name: string
//   age: number
//   // gender 的数据类型是可变化的, 需要跟随使用的时候来决定
//   gender: GX
// }
// // 今后使用这个接口的时候
// enum GenderType {
//   A = '男',
//   B = '女'
// }
// const user: UserType<string> = { name: 'Jack', age: 18, gender: '男' }
// const user2: UserType<number> = { name: 'Jack', age: 20, gender: 1 }
// const user3: UserType<GenderType> = { name: 'Jack', age: 20, gender: GenderType.A }

/* 7. 断言
  + 私人: TS 内的一道光
  + 断言就是我告诉你这里一定是 xxx, 不需要你去帮我判断是不是 null 是不是 undefined
*/
// 获取页面元素
// const ele = document.querySelector('div') as HTMLDivElement
// // 给获取到的元素添加一个点击事件
// // 报错原因 : 因为你有可能获取不到元素, 你的 ele 有可能是 页面元素, 也有可能是 null
// //           如果是页面元素, 绑定 onclick 没有问题
// //           如果是 null, 没办法绑定 onclick
// ele.onclick = function () {}

/* 8. 函数的重载
  + 当你有多个可能性的时候
  + 提前把每一个可能性列出来
*/
// 例子: 需求 -> 如果你调用函数传递的事 number, 返回值就是该数字放大 100 倍, 如果你调用函数传递的是 string, 返回值就是反转该字符串
// function fn(x: number): (number)
// function fn(x: string): (string)
// function fn(x: number | string): (number | string) {
//   if (typeof x === 'number') {
//     return x * 100
//   }
//
//   if (typeof x === 'string') {
//     return x.split('').reverse().join('')
//   }
// }
// 开始使用
// const r1 = fn(100)
// 报错原因:
//   根据你的函数定义, 该函数的返回值是 string或者number
//   在得道 r1 返回值的时候, 有可能是 string, 也有可能是 number
//   你在调用 toFixed 方法的时候, 有可能报错
// r1.toFixed(2)
